convert random format to Format class. (#528)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Tue, 31 Mar 2020 22:40:22 +0000 (16:40 -0600)
committerGitHub <noreply@github.com>
Tue, 31 Mar 2020 22:40:22 +0000 (16:40 -0600)
CMakeLists.txt
GPSBabel.pro
Makefile.in
random.cc
random.h [new file with mode: 0644]
vecs.h

index 054a25255376ab7ad285524d4929a6cd86894881..02defda1014f6461ae22fc74daa604de65c75e28 100644 (file)
@@ -152,6 +152,7 @@ set(HEADERS
   mynav.h
   navilink.h
   nmea.h
+  random.h
   session.h
   shape.h
   shapelib/shapefil.h
index 5d28e4e67e3a6f98d21994d5565b13cd33458d4f..a05a3081c0ecc933761ba924127139999fabb9eb 100644 (file)
@@ -137,6 +137,7 @@ HEADERS =  \
        mynav.h \
        navilink.h \
        nmea.h \
+       random.h \
        session.h \
        shape.h \
        shapelib/shapefil.h \
index c619865edccb9721b737c2c3cdb7a0e5c8a8a3a9..6f7b1eeab7ebf393fda294538c54cde9a9f347f2 100644 (file)
@@ -512,11 +512,12 @@ filter_vecs.o: filter_vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   swapdata.h trackfilter.h transform.h validate.h gbversion.h vecs.h \
   format.h geojson.h src/core/file.h ggv_bin.h gpx.h \
   src/core/xmlstreamwriter.h src/core/xmltag.h legacyformat.h mynav.h \
-  nmea.h shape.h shapelib/shapefil.h xcsv.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h src/core/textstream.h yahoo.h xmlgeneric.h
+  nmea.h random.h shape.h shapelib/shapefil.h xcsv.h garmin_fs.h \
+  jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
+  jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+  jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+  jeeps/gpsmem.h jeeps/gpsrqst.h src/core/textstream.h yahoo.h \
+  xmlgeneric.h
 formspec.o: formspec.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
   src/core/optional.h
@@ -535,7 +536,7 @@ garmin.o: garmin.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h garmin_tables.h grtcirc.h jeeps/gpsserial.h vecs.h \
   geojson.h src/core/file.h ggv_bin.h gpx.h src/core/xmlstreamwriter.h \
-  src/core/xmltag.h legacyformat.h mynav.h nmea.h shape.h \
+  src/core/xmltag.h legacyformat.h mynav.h nmea.h random.h shape.h \
   shapelib/shapefil.h xcsv.h src/core/textstream.h yahoo.h xmlgeneric.h
 garmin_device_xml.o: garmin_device_xml.cc defs.h config.h zlib/zlib.h \
   zlib/zconf.h formspec.h inifile.h gbfile.h session.h \
@@ -818,7 +819,7 @@ magproto.o: magproto.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
   src/core/optional.h explorist_ini.h format.h gbser.h magellan.h vecs.h \
   geojson.h src/core/file.h ggv_bin.h gpx.h src/core/xmlstreamwriter.h \
-  src/core/xmltag.h legacyformat.h mynav.h nmea.h shape.h \
+  src/core/xmltag.h legacyformat.h mynav.h nmea.h random.h shape.h \
   shapelib/shapefil.h xcsv.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
   jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
   jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
@@ -832,7 +833,7 @@ main.o: main.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   stackfilter.h swapdata.h trackfilter.h transform.h validate.h format.h \
   src/core/file.h src/core/usasciicodec.h vecs.h geojson.h ggv_bin.h \
   gpx.h src/core/xmlstreamwriter.h src/core/xmltag.h legacyformat.h \
-  mynav.h nmea.h shape.h shapelib/shapefil.h xcsv.h garmin_fs.h \
+  mynav.h nmea.h random.h shape.h shapelib/shapefil.h xcsv.h garmin_fs.h \
   jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
   jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
   jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
@@ -927,10 +928,10 @@ radius.o: radius.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   radius.h filter.h grtcirc.h
 random.o: random.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
-  garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
-  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
-  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
-  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
+  random.h format.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
+  jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
+  jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
+  jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h
 raymarine.o: raymarine.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
   src/core/optional.h csv_util.h
@@ -1050,12 +1051,12 @@ vecs.o: vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
   vecs.h format.h geojson.h src/core/file.h ggv_bin.h gpx.h \
   src/core/xmlstreamwriter.h src/core/xmltag.h legacyformat.h mynav.h \
-  nmea.h shape.h shapelib/shapefil.h xcsv.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h src/core/textstream.h yahoo.h xmlgeneric.h gbversion.h \
-  src/core/logging.h
+  nmea.h random.h shape.h shapelib/shapefil.h xcsv.h garmin_fs.h \
+  jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
+  jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
+  jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
+  jeeps/gpsmem.h jeeps/gpsrqst.h src/core/textstream.h yahoo.h \
+  xmlgeneric.h gbversion.h src/core/logging.h
 vidaone.o: vidaone.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
 vitosmt.o: vitosmt.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
index 175d7be09639b1877e069f1fa36b703049662707..7cd28e89a8a835e4182d7821c1b54e1284dad09e 100644 (file)
--- a/random.cc
+++ b/random.cc
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#include <cstdlib>           // for atoi
-#include <random>            // for mt19937
+#include <cstdlib>              // for atoi
+#include <random>               // for mt19937
 
-#include <QtCore/QDateTime>  // for QDateTime
-#include <QtCore/QString>    // for QString
-#include <QtCore/QThread>    // for QThread
-#include <QtCore/QVector>    // for QVector
+#include <QtCore/QByteArray>    // for QByteArray
+#include <QtCore/QByteRef>      // for QByteRef
+#include <QtCore/QDateTime>     // for QDateTime
+#include <QtCore/QString>       // for QString
+#include <QtCore/QThread>       // for QThread
 
 #include "defs.h"
-#include "garmin_fs.h"       // for garmin_fs_t, GMSD_SET, garmin_fs_flags_t, garmin_fs_alloc
-
-#define MYNAME "random"
-
-static char* opt_points, *opt_seed, *opt_nodelay;
-
-static QVector<arglist_t> random_args = {
-  {
-    "points", &opt_points, "Generate # points", nullptr,
-    ARGTYPE_INT, "1", nullptr, nullptr
-  },
-  {
-    "seed", &opt_seed, "Starting seed of the internal number generator", nullptr,
-    ARGTYPE_INT, "1", nullptr, nullptr
-  },
-  {
-    "nodelay", &opt_nodelay, "Output realtime points without delay", nullptr,
-    ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
-  },
-};
-
-//  this generator is invariant across platforms.
-static std::mt19937* generator;
-
-// we do this cheesy distribution function because we need it to be invariant across platforms.
-// note uniform_int_distribution is not invariant.
-template <typename T>
-static T
-rand_num(const T max)
-{
-  T retval;
-  // scalefactor expression assumes generator is mt19937.
-  constexpr double scalefactor = 1.0 / std::mt19937::max();
-  do {
-    retval = static_cast<T>(static_cast<double>(max) * scalefactor * (*generator)());
-  } while (retval >= max);
-  return retval;
-}
+#include "random.h"
+#include "formspec.h"           // for FormatSpecificDataList
+#include "garmin_fs.h"          // for garmin_fs_t, GMSD_SET, garmin_fs_flags_t, garmin_fs_alloc
+#include "src/core/datetime.h"  // for DateTime
 
-static double
-rand_dbl(const double max)
+
+double
+RandomFormat::rand_dbl(const double max)
 {
   return rand_num(max);
 }
 
-static float
-rand_flt(const float max)
+float
+RandomFormat::rand_flt(const float max)
 {
   return rand_num(max);
 }
 
-static int
-rand_int(const int max)
+int
+RandomFormat::rand_int(const int max)
 {
   return rand_num(max);
 }
 
 /* rand_str always returns a valid string with len >= 0 */
 
-static QString
-rand_str(const int maxlen, const char* fmt)
+QString
+RandomFormat::rand_str(const int maxlen, const char* fmt)
 {
   int len = rand_int(maxlen) + 1;
 
@@ -109,8 +77,8 @@ rand_str(const int maxlen, const char* fmt)
          QString::asprintf(fmt, res.constData()) : QString(res);
 }
 
-static void
-random_set_generator()
+void
+RandomFormat::random_set_generator()
 {
   generator = new std::mt19937;
   if (opt_seed) {
@@ -120,119 +88,118 @@ random_set_generator()
   }
 }
 
-static void
-random_rd_init(const QString&)
+void
+RandomFormat::rd_init(const QString&)
 {
   random_set_generator();
 }
 
-static void
-random_rd_deinit()
+void
+RandomFormat::rd_deinit()
 {
   delete generator;
 }
 
 #define RND(a) (rand_int(a) > 0)
 
-static Waypoint*
-random_generate_wpt(int i, const QDateTime& time, const Waypoint* prev)
+Waypoint*
+RandomFormat::random_generate_wpt(int i, const QDateTime& time, const Waypoint* prev)
 {
-    auto wpt = new Waypoint;
-    garmin_fs_t* gmsd = garmin_fs_alloc(-1);
-    wpt->fs.FsChainAdd(gmsd);
+  auto wpt = new Waypoint;
+  garmin_fs_t* gmsd = garmin_fs_alloc(-1);
+  wpt->fs.FsChainAdd(gmsd);
 
-    do {
-      wpt->shortname = rand_str(8, "Wpt_%s");
-    } while (wpt->shortname == nullptr);
+  do {
+    wpt->shortname = rand_str(8, "Wpt_%s");
+  } while (wpt->shortname == nullptr);
 
-    wpt->latitude = rand_dbl(180.0) - 90.0;
-    wpt->longitude = rand_dbl(360.0) - 180.0;
+  wpt->latitude = rand_dbl(180.0) - 90.0;
+  wpt->longitude = rand_dbl(360.0) - 180.0;
 
-    /* !!! "if RND(3) ..." produces some leaks in generated data !!! */
+  /* !!! "if RND(3) ..." produces some leaks in generated data !!! */
 
+  if RND(3) {
+    wpt->altitude = rand_dbl(100.0);
+  }
+  if RND(3) {
+    WAYPT_SET(wpt, temperature, rand_flt(32.0f));
+  }
+  if RND(3) {
+    WAYPT_SET(wpt, proximity, rand_dbl(1000.0));
+  }
+  if RND(3) {
+    WAYPT_SET(wpt, depth, rand_dbl(1000.0));
+  }
+  if RND(3) {
+    wpt->AddUrlLink(rand_str(8, "http://link1.example.com/%s"));
+    if RND(3) {
+      wpt->AddUrlLink(rand_str(8, "http://link2.example.com/%s"));
+    }
+  }
+  if RND(3) {
+    wpt->icon_descr = rand_str(3, "Icon_%s");
+  }
+
+  wpt->SetCreationTime(time);
+
+  if (doing_trks || doing_posn) {
+    if (i > 0) {
+      wpt->latitude = prev->latitude + rand_dbl(0.001);
+      wpt->longitude = prev->longitude + rand_dbl(0.001);
+      WAYPT_SET(wpt, course, waypt_course(prev, wpt));
+      WAYPT_SET(wpt, speed, waypt_speed(prev, wpt));
+    }
+    wpt->sat = rand_int(12 + 1);
+    wpt->hdop = rand_flt(50.0f);
+    wpt->vdop = rand_flt(50.0f);
+    wpt->pdop = rand_flt(50.0f);
+    wpt->fix = (fix_type)(rand_int(6) - 1);
     if RND(3) {
-      wpt->altitude = rand_dbl(100.0);
+      wpt->cadence = rand_int(255);
     }
     if RND(3) {
-      WAYPT_SET(wpt, temperature, rand_flt(32.0f));
+      wpt->heartrate = rand_int(255);
+    }
+  } else {
+    if (doing_rtes && (i > 0)) {
+      wpt->latitude = prev->latitude + rand_dbl(0.01);
+      wpt->longitude = prev->longitude + rand_dbl(0.01);
     }
     if RND(3) {
-      WAYPT_SET(wpt, proximity, rand_dbl(1000.0));
+      wpt->description = rand_str(16, "Des_%s");
     }
     if RND(3) {
-      WAYPT_SET(wpt, depth, rand_dbl(1000.0));
+      wpt->notes = rand_str(16, "Nts_%s");
     }
     if RND(3) {
-      wpt->AddUrlLink(rand_str(8, "http://link1.example.com/%s"));
-      if RND(3) {
-        wpt->AddUrlLink(rand_str(8, "http://link2.example.com/%s"));
-      }
+      garmin_fs_t::set_addr(gmsd, rand_str(8, "Adr_%s"));
     }
     if RND(3) {
-      wpt->icon_descr = rand_str(3, "Icon_%s");
+      garmin_fs_t::set_city(gmsd, rand_str(8, "Cty_%s"));
     }
-
-    wpt->SetCreationTime(time);
-
-    if (doing_trks || doing_posn) {
-      if (i > 0) {
-        wpt->latitude = prev->latitude + rand_dbl(0.001);
-        wpt->longitude = prev->longitude + rand_dbl(0.001);
-        WAYPT_SET(wpt, course, waypt_course(prev, wpt));
-        WAYPT_SET(wpt, speed, waypt_speed(prev, wpt));
-      }
-      wpt->sat = rand_int(12 + 1);
-      wpt->hdop = rand_flt(50.0f);
-      wpt->vdop = rand_flt(50.0f);
-      wpt->pdop = rand_flt(50.0f);
-      wpt->fix = (fix_type)(rand_int(6) - 1);
-      if RND(3) {
-        wpt->cadence = rand_int(255);
-      }
-      if RND(3) {
-        wpt->heartrate = rand_int(255);
-      }
-    } else {
-      if (doing_rtes && (i > 0)) {
-        wpt->latitude = prev->latitude + rand_dbl(0.01);
-        wpt->longitude = prev->longitude + rand_dbl(0.01);
-      }
-      if RND(3) {
-        wpt->description = rand_str(16, "Des_%s");
-      }
-      if RND(3) {
-        wpt->notes = rand_str(16, "Nts_%s");
-      }
-      if RND(3) {
-        garmin_fs_t::set_addr(gmsd, rand_str(8, "Adr_%s"));
-      }
-      if RND(3) {
-        garmin_fs_t::set_city(gmsd, rand_str(8, "Cty_%s"));
-      }
-      if RND(3) {
-        garmin_fs_t::set_facility(gmsd, rand_str(8, "Fac_%s"));
-      }
-      if RND(3) {
-        garmin_fs_t::set_country(gmsd, rand_str(8, "Ctr_%s"));
-      }
-      if RND(3) {
-        garmin_fs_t::set_state(gmsd, rand_str(8, "Sta_%s"));
-      }
-      if RND(3) {
-        garmin_fs_t::set_phone_nr(gmsd, rand_str(8, "Pnr_%s"));
-      }
-      if RND(3) {
-        garmin_fs_t::set_postal_code(gmsd, rand_str(8, "Pcd_%s"));
-      }
+    if RND(3) {
+      garmin_fs_t::set_facility(gmsd, rand_str(8, "Fac_%s"));
     }
+    if RND(3) {
+      garmin_fs_t::set_country(gmsd, rand_str(8, "Ctr_%s"));
+    }
+    if RND(3) {
+      garmin_fs_t::set_state(gmsd, rand_str(8, "Sta_%s"));
+    }
+    if RND(3) {
+      garmin_fs_t::set_phone_nr(gmsd, rand_str(8, "Pnr_%s"));
+    }
+    if RND(3) {
+      garmin_fs_t::set_postal_code(gmsd, rand_str(8, "Pcd_%s"));
+    }
+  }
 
   return wpt;
 }
 
-static void
-random_read()
+void
+RandomFormat::read()
 {
-
   route_head* head;
   Waypoint* prev = nullptr;
   QDateTime time = current_time().toUTC();
@@ -248,7 +215,7 @@ random_read()
       route_add_head(head);
     }
     head->rte_desc = rand_str(16, nullptr);
-       if RND(3) {
+    if RND(3) {
       head->rte_urls.AddUrlLink(UrlLink(rand_str(8, "http://rteurl.example.com/%s")));
     }
   } else {
@@ -270,16 +237,8 @@ random_read()
   }
 }
 
-struct realtime_data {
-  QDateTime time;
-  int points{-1};
-  int point_count{0};
-  Waypoint prev;
-};
-static realtime_data* realtime;
-
 void
-random_rd_posn_init(const QString&)
+RandomFormat::rd_position_init(const QString&)
 {
   random_set_generator();
   realtime = new realtime_data;
@@ -290,19 +249,19 @@ random_rd_posn_init(const QString&)
 }
 
 void
-random_rd_posn_deinit()
+RandomFormat::rd_position_deinit()
 {
   delete generator;
   delete realtime;
 }
 
-static Waypoint*
-random_rd_posn(posn_status* p_status)
+Waypoint*
+RandomFormat::rd_position(posn_status* status)
 {
   Waypoint* wpt = random_generate_wpt(realtime->point_count, realtime->time, &(realtime->prev));
 
-  if (p_status && (realtime->points > 0) && (realtime->point_count >= realtime->points)) {
-    p_status->request_terminate = 1;
+  if (status && (realtime->points > 0) && (realtime->point_count >= realtime->points)) {
+    status->request_terminate = 1;
   }
   ++realtime->point_count;
 
@@ -319,26 +278,3 @@ random_rd_posn(posn_status* p_status)
 
   return wpt;
 }
-
-ff_vecs_t random_vecs = {
-  ff_type_internal,
-  {
-    ff_cap_read /* waypoints */,
-    ff_cap_read /* tracks */,
-    ff_cap_read /* routes */
-  },
-  random_rd_init,
-  nullptr,     /* wr_init */
-  random_rd_deinit,
-  nullptr,     /* wr_deinit */
-  random_read,
-  nullptr,     /* write */
-  nullptr,     /* exit */
-  &random_args,
-  CET_CHARSET_ASCII, 1,                        /* fixed */
-  {
-  random_rd_posn_init, random_rd_posn, random_rd_posn_deinit,
-  nullptr, nullptr, nullptr,
-  },
-  nullptr
-};
diff --git a/random.h b/random.h
new file mode 100644 (file)
index 0000000..0c53db0
--- /dev/null
+++ b/random.h
@@ -0,0 +1,134 @@
+/*
+    random - GPS data generator
+
+    Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+#ifndef RANDOM_H_INCLUDED_
+#define RANDOM_H_INCLUDED_
+
+#include <random>            // for mt19937
+
+#include <QtCore/QDateTime>  // for QDateTime
+#include <QtCore/QString>    // for QString
+#include <QtCore/QVector>    // for QVector
+
+#include "defs.h"
+#include "format.h"
+
+
+class RandomFormat : public Format
+{
+public:
+  /* Member Functions */
+
+  QVector<arglist_t>* get_args() override
+  {
+    return &random_args;
+  }
+
+  ff_type get_type() const override
+  {
+    return ff_type_internal;
+  }
+
+  QVector<ff_cap> get_cap() const override
+  {
+    return {
+      ff_cap_read /* waypoints */,
+      ff_cap_read /* tracks */,
+      ff_cap_read /* routes */
+    };
+  }
+
+  QString get_encode() const override
+  {
+    return CET_CHARSET_ASCII;
+  }
+
+  int get_fixed_encode() const override
+  {
+    return 1;
+  }
+
+  void rd_init(const QString& fname) override;
+  void read() override;
+  void rd_deinit() override;
+  void rd_position_init(const QString& fname) override;
+  Waypoint* rd_position(posn_status* status) override;
+  void rd_position_deinit() override;
+
+private:
+  /* Types */
+
+  struct realtime_data {
+    QDateTime time;
+    int points{-1};
+    int point_count{0};
+    Waypoint prev;
+  };
+
+  /* Member Functions */
+
+  double rand_dbl(double);
+  float rand_flt(float);
+  int rand_int(int);
+  QString rand_str(int, const char*);
+  void random_set_generator();
+  Waypoint* random_generate_wpt(int, const QDateTime&, const Waypoint*);
+
+  /* Data Members */
+
+  char* opt_points{nullptr};
+  char* opt_seed{nullptr};
+  char* opt_nodelay{nullptr};
+
+  QVector<arglist_t> random_args = {
+    {
+      "points", &opt_points, "Generate # points", nullptr,
+      ARGTYPE_INT, "1", nullptr, nullptr
+    },
+    {
+      "seed", &opt_seed, "Starting seed of the internal number generator", nullptr,
+      ARGTYPE_INT, "1", nullptr, nullptr
+    },
+    {
+      "nodelay", &opt_nodelay, "Output realtime points without delay", nullptr,
+      ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+    },
+  };
+
+//  this generator is invariant across platforms.
+  std::mt19937* generator{nullptr};
+
+// we do this cheesy distribution function because we need it to be invariant across platforms.
+// note uniform_int_distribution is not invariant.
+  template <typename T>
+  T
+  rand_num(const T max)
+  {
+    T retval;
+    // scalefactor expression assumes generator is mt19937.
+    constexpr double scalefactor = 1.0 / std::mt19937::max();
+    do {
+      retval = static_cast<T>(static_cast<double>(max) * scalefactor * (*generator)());
+    } while (retval >= max);
+    return retval;
+  }
+
+  realtime_data* realtime{nullptr};
+};
+#endif // RANDOM_H_INCLUDED_
diff --git a/vecs.h b/vecs.h
index 9cbadfd434ef410010a369956b2c783cfb0e0c16..60797116b91572c691f7a885f10708b03ec4726a 100644 (file)
--- a/vecs.h
+++ b/vecs.h
@@ -35,6 +35,7 @@
 #include "legacyformat.h"
 #include "mynav.h"
 #include "nmea.h"
+#include "random.h"
 #include "shape.h"
 #include "xcsv.h"
 #include "yahoo.h"
@@ -123,7 +124,6 @@ extern ff_vecs_t g7towin_vecs;
 #endif // CSVFMTS_ENABLED
 extern ff_vecs_t garmin_gpi_vecs;
 extern ff_vecs_t lmx_vecs;
-extern ff_vecs_t random_vecs;
 extern ff_vecs_t xol_vecs;
 extern ff_vecs_t dg100_vecs;
 extern ff_vecs_t dg200_vecs;
@@ -355,7 +355,7 @@ private:
 #endif // CSVFMTS_ENABLED
   LegacyFormat garmin_gpi_fmt {garmin_gpi_vecs};
   LegacyFormat lmx_fmt {lmx_vecs};
-  LegacyFormat random_fmt {random_vecs};
+  RandomFormat random_fmt;
   LegacyFormat xol_fmt {xol_vecs};
   LegacyFormat dg100_fmt {dg100_vecs};
   LegacyFormat dg200_fmt {dg200_vecs};